<?php

namespace app\socketio\controller;

use Workerman\Worker;
use Workerman\Lib\Timer;
use PHPSocketIO\SocketIO;
use think\Db;

class Subscribe
{
    private $redis;

    public function __construct()
    {

    }

    public function Index()
    {
        $worker = new Worker();

        $worker->count = 1;

        $worker->onWorkerStart = function () {
            $this->redis = new \Redis();
            $this->redis->connect(config('huisheng.redis_ip'), config('huisheng.redis_port'));
            $this->redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
            $this->redis->subscribe(['send audio info'], array($this, 'callback'));
        };

        Worker::runAll();
    }

    public function callback($redis, $chan, $msg)
    {
        try {
            switch ($chan) {
                case 'send audio info':
                    $this->sendAudioInfo($msg);
                    break;
                default:
                    break;
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
            return;
        }
    }

    private function sendAudioInfo($msg)
    {
        $redis = new \Redis();
        $redis->connect(config('huisheng.redis_ip'), config('huisheng.redis_port'));

        //校验数据
        $msg_data = json_decode($msg, true);
        if (!$msg_data) {
            //如果数据格式不正确，返回错误信息
            throw new \Exception("数据格式不正确。。");
        }
        //获取meetingid
        $mid = $msg_data['meeting_id'];
        //获取meeting对应表的lid
        $lid = $redis->hGet('meeting_to_lid', $mid);
        //判断meeting是否储存在对应表id的hash中
        if (!$lid) {
            //如果不存在则 查找并添加入hash
            $lid = Db::name('meeting_live_speech')->where('meeting_tag', $mid)->field('id')->find()['id'];
            //$lid = $mysql->select('id')->from('rszh_meeting_live_speech')->where('meeting_tag = :mid')->bindValues(['mid' => $mid])->query();
            //如果不在数据库，则return
            if (empty($lid)) {
                throw new \Exception("会议id - $mid 的文件在数据库不存在");
            }
            //$lid = $lid[0]['id'];
            $redis->hSet('meeting_to_lid', $mid, $lid);
        }
        //数据处理
        $transfer = [
            'or_txt' => $msg_data['raw_text'],
            'ed_txt' => '',
            'url' => substr($msg_data['url'], strpos($msg_data['url'], "/audio/")),
            'paly_time' => $msg_data['pcmtime'],
            'status' => $msg_data['end_of_speech'],
            'timestamp' => $msg_data['timestamp'],
            'is_edit' => 0,
        ];
        $pagh = false;
        //初始化
        $sorting = 1;
        //查看储存该转写结果的状态是否存在
        if (!$redis->hGet($mid . "_state", 'lower')) {
            //不存在则 创建string储存结果状态
            //string
            $redis->hMSet($mid . "_state", ['subsection' => 0, 'lower' => $sorting, 'editstate' => 0, 'lastTime' => 0]);
            $redis->expire($mid . "_state", 60 * 60 * 24);
            //上传web
        }

        //如果存在则判断end_of_speech是否为1
        if ($msg_data['end_of_speech']) {
            //获取当前排序
            $sorting = $redis->hGet($mid . "_state", 'lower');
            //修改meeting_state
            $redis->hSet($mid . "_state", 'lower', $sorting + 1);
            $redis->expire($mid . "_state", 60 * 60 * 24);
            //该句结束，则储存hash
            $transfer['sorting'] = $sorting;
            //分段准备 redis中加入文字数量字段 end_of_speech为1则计算该段落总字数
            $txtCount = ($redis->hGet($mid . "_state", 'txtCount') ?: 0) + mb_strlen($transfer['or_txt'], 'utf8');
            //判断分段条件
            $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
            if ($txtCount >= 100 && preg_match("/(\。)$/", $transfer['or_txt'])) {
                $redis->hIncrBy($mid . "_state", 'subsection', 1);
                $txtCount = 0;
                //分段
                $br = [
                    'or_txt' => '<br>',
                    'ed_txt' => '',
                    'url' => '',
                    'paly_time' => 0,
                    'status' => 1,
                    'timestamp' => '',
                    'sc' => $transfer['sc']
                ];
                $pagh = true;
            }
            //更新当前文字数量
            $redis->hSet($mid . "_state", 'txtCount', $txtCount);

            //hash
            $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
            //$redis->hSet($mid, $sorting, json_encode($transfer));
            $redis->expire($mid, 60 * 60 * 24);
            //并且存入数据库
            $save = [
                "lid" => $lid,
                "transfer" => $transfer['or_txt'],
                "editor" => $transfer['ed_txt'],
                "url" => $transfer['url'],
                "pcmtime" => $transfer['paly_time'] . '',
                "sorting" => $sorting + 0,
                "subsection" => $transfer['sc'],
                "create_time" => time()
            ];
            //判断是否成功以后加
            $lid = Db::name('meeting_convert')->insertGetId($save);
            //$lid = $mysql->insert('rszh_meeting_convert')->cols($save)->query();
        }
        ////如果存在end_of_speech为0
        else {
            //获取当前排序
            $sorting = $redis->hGet($mid . "_state", 'lower');
            $transfer['sorting'] = $sorting;
            //获取当前结果hash中对应的数据
            $result_json = $redis->hGet($mid, $sorting);
            //判断当前结果数据和新上传的值是否相同
            if ($result_json) {
                $result = json_decode($result_json, true);
                if ($result['or_txt'] == $transfer['or_txt']) {
                    return;
                }
                $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
            }
            //如果值不同，存入结果hash
            $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
            //$redis->hSet($mid, $sorting, json_encode($transfer));
            $redis->expire($mid, 60 * 60 * 24);
        }

        //传给web
        //$io->to($mid)->emit('get audio info', $transfer);
        $msg = [
            'mid' => $mid,
            'transfer' => $transfer
        ];
        $redis->lPush('meeting_transfer', json_encode($msg));
        if ($pagh) {
            $msg = [
                'mid' => $mid,
                'transfer' => $br
            ];
            //$io->to($mid)->emit('get audio info', $br);
            $redis->lPush('meeting_transfer', json_encode($msg));
        }
    }
}
